﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.ComponentModel;
namespace pipeCore.Pipes.Units.NamedPortUnits.ports
{
    
      
    /// <summary>
    ///  this implement a simple output port 
    /// </summary>
         public class Outport : pipeCore.Pipes.Ports.Ioutport
        {
            NamedPipeClientStream _client;
            StreamWriter _writer;
            /// <summary>
            /// Constratc a new Output port
            /// </summary>
            /// <param name="name">port name</param>
            public Outport(String name)
            {
                Name = name;
                initailizePipe();
                
            }
            /// <summary>
            /// Constract a new Outputport
            /// </summary>
            /// <param name="name">port name</param>
            /// <param name="tag">port tag</param>
            public Outport(string name,string tag)
            {
                Name = name;
                Tag = tag;
                initailizePipe();
            }
            /// <summary>
            /// A text discribing the port
            /// </summary>
            public string Discport
            {
                get;
                set;
            }
            /// <summary>
            /// Send the data to the next port
            /// </summary>
            public void Send()
            {

                if (_client.IsConnected)
                {
                    _writer.WriteLine(System.Text.ASCIIEncoding.ASCII.GetString(Data));
                    _writer.Flush();
                    _client.Flush();
               
                }
                else
                {
                    throw new Exception("the port is not connected to the remmot site");
                }
                
            }
            /// <summary>
            /// Sends a String Message
            /// </summary>
            /// <param name="Message"></param>
            public void Send(String Message)
            {
                Data = System.Text.ASCIIEncoding.ASCII.GetBytes(Message);
                _writer.WriteLine(Message);
                _writer.Flush();
                _client.Flush();
            }
            /// <summary>
            /// Connect the port to the remoPort
            /// </summary>
            /// <param name="remotPort">the remot port name</param>
            public virtual void Connect(string remotPort)
            {
                _client = new NamedPipeClientStream(".",remotPort, PipeDirection.InOut);
                _client.Connect();
                _writer = new StreamWriter(_client);
                _writer.AutoFlush = true;
                
               
                
            }
            /// <summary>
            /// the port name
            /// </summary>
            public string Name
            {
                get;
                set;
            }
            /// <summary>
            /// report tag that represent any addtion script about the port
            /// </summary>
            public string Tag
            {
                get;
                set;
            }
            /// <summary>
            /// A text discribing the port functionality
            /// </summary>
            public string Discribtion
            {
                get;
                set;
            }
            /// <summary>
            /// the data buffer that holds the send data
            /// </summary>
            public byte[] Data
            {
                get;
                set;
            }

            /// <summary>
            /// Stop the port and close any stream and clean it, to use it the program must call connect 
            /// </summary>
            public void Stop()
            {
                _writer.Close();
                _writer.Dispose();
                _client.Close();
                _writer.Dispose();
            }
       
             void initailizePipe()
            {
                
            }
             ISite site;
             /// <summary>
             /// inherited from ICOmponent
             /// </summary>
             public event EventHandler Disposed;
             /// <summary>
             /// Inherited from ICOmponent
             /// </summary>
             public ISite Site
             {
                 get
                 {
                     return site;
                 }
                 set
                 {
                     site=value;
                 }
             }
             /// <summary>
             /// Inherited from ICOmponent
             /// </summary>
             public void Dispose()
             {
                 _writer.Dispose();
                 _client.Dispose();
             }
        }
   
   /// <summary>
         /// this implement a simple inport
   /// </summary>

         public class Inport :pipeCore.Pipes.Ports.Iinport
         {
             NamedPipeServerStream _server;
             StreamReader _reader;
             /// <summary>
             /// Constract a new inport
             /// </summary>
             /// <param name="name">port name</param>
             public Inport(String name)
             {
                 Name = name;
                 _server = new NamedPipeServerStream(name,PipeDirection.InOut,1,PipeTransmissionMode.Message);
                 
                 _reader = new StreamReader(_server);
                  IsListing = true;
                 
             }
             /// <summary>
             /// An event handler that will be triggerd when in an incoming message is presnt
             /// </summary>
             public event EventHandler<Ports.OnMessageRecivedEventArg> OnMessageRecive;
             private bool IsListing;
             /// <summary>
             /// Start the port Listening
             /// </summary>
             public void Listen()
             {
                 

                 Action act = new Action(() =>
                 {
                     try
                     {
                         _server.WaitForConnection();
                         while (IsListing)
                         {
                             String line;
                             while ((line = _reader.ReadLine()) != null)
                             {
                                 OnMessageRecive(this, new Ports.OnMessageRecivedEventArg(System.Text.ASCIIEncoding.ASCII.GetBytes(line),this.Name));
                             }
                         }
                        
                     }
                     catch (Exception err)
                     {
                         throw new Exception(err.Message);
                     }
                 });
                 System.Threading.Tasks.TaskFactory tasks = new System.Threading.Tasks.TaskFactory();
                 tasks.StartNew(act);
        
        
        
        
             }
             /// <summary>
             /// The port name
             /// </summary>
             public string Name
             {
                 get;
                 set;
             }
             /// <summary>
             /// The port tag
             /// </summary>
             public string Tag
             {
                 get;
                 set;
             }
             /// <summary>
             /// The port discribtion
             /// </summary>
             public string Discribtion
             {
                 get;
                 set;
             }
             /// <summary>
             /// The buffer that will hold the data
             /// </summary>
             public byte[] Data
             {
                 get;
                 set;
             }
             /// <summary>
             /// Stop and clear the port
             /// </summary>
             public void Stop()
             {
                 IsListing = false;
                 _reader.Close();
                 _server.Disconnect();
             }

             ISite site;
             /// <summary>
             /// inherited from IComponent
             /// </summary>
             public event EventHandler Disposed;
             /// <summary>
             /// inhireted from IComponent
             /// </summary>
             public System.ComponentModel.ISite Site
             {
                 get
                 {
                     return site;
                 }
                 set
                 {
                     site = value;
                 }
             }
             /// <summary>
             /// inherited from IComponent
             /// </summary>
             public void Dispose()
             {
                 _reader.Dispose();
                 _server.Dispose();
                
             }
            
         }

}
